import { existsSync, mkdirSync, readdirSync, readFile, readFileSync } from 'fs';
import { resolve } from 'path';
import { SourceMapConsumer } from 'source-map';

export const getCookieExpireDate = (seconds: number = 60) => {
  const date: Date = new Date();
  date.setSeconds(date.getSeconds() + seconds);
  return date;
};

// 读取压缩代码和对应的source map
const path = resolve(__dirname, '../../maps');
let sourceMap = {};
if (!existsSync(path)) {
  mkdirSync(path, { recursive: true });
}
const files = readdirSync(path);
for (const file of files) {
  readFile(
    resolve(__dirname, '../../maps', file),
    'utf-8',
    function (err, data) {
      if (err) {
        return err;
      }
      sourceMap[file] = data;
    },
  );
}

export const clearMap = () => {
  sourceMap = {};
};

export const setMap = (fileName: string, source: string) => {
  sourceMap[fileName] = source;
};

export const getMap = (fileName: string) => {
  return sourceMap[fileName];
};

export type MessageInfo = {
  message: string;
  lineNumber: number;
  column: number;
  source: string;
};

export type ErrorPosition = {
  file?: string;
  line?: number;
  column?: number;
  message?: string;
};

export const handleErrorMessage = (msg: MessageInfo) => {
  return new Promise<ErrorPosition>((res, rej) => {
    const errorLine = msg.lineNumber;
    const errorCol = msg.column;
    const jsName = msg.source.split('/').pop();
    const sourceName = jsName + '.map';
    // 服务器因为是一直启动状态，所以如果是在启动后最新上传的文件，则需要事实进行读取对应的map文件
    if (!sourceMap[sourceName]) {
      try {
        sourceMap[sourceName] = readFileSync(
          resolve(__dirname, './maps', sourceName),
          'utf-8',
        );
      } catch (error) {
        res({});
        return;
      }
    }
    SourceMapConsumer.with(sourceMap[sourceName], null, (consumer) => {
      // 在源码堆栈中定位报错位置
      const originalPosition = consumer.originalPositionFor({
        line: errorLine,
        column: errorCol,
      });
      res({
        file: originalPosition.source,
        line: originalPosition.line,
        column: originalPosition.column,
        message: msg.message,
      });
    });
  });
};
